import com.fasterxml.jackson.databind.ObjectMapper;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

class Confession{
    public String from;
    public String to;
    public String message;
}
@WebServlet("/confession")
public class confessionServlet extends HttpServlet {
    private ObjectMapper objectMapper = new ObjectMapper();
    //private List<Confession> confessionList = new ArrayList<>();

    // 这个是保存文件的路径
    private String filePath = "d:/confessionWall.txt";

//    @Override
//    public void init() throws ServletException {
//        // 这里是为了构造几个测试用例
//        Confession confession1 = new Confession();
//        confession1.from = "wz";
//        confession1.to = "zw";
//        confession1.message = "wwwzzz";
//        confessionList.add(confession1);
//
//        Confession confession2 = new Confession();
//        confession2.from = "zw";
//        confession2.to = "wz";
//        confession2.message = "zzzwww";
//        confessionList.add(confession2);
//    }

    // 这个用来处理从服务器获取到消息数据
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("application/json;charset=utf-8");
        //objectMapper.writeValue(resp.getWriter(),confessionList);
        List<Confession> confessionList = load1();
        objectMapper.writeValue(resp.getWriter(),confessionList);
    }

    /**
     * 从数据库中读取数据
     * @return
     */
    private List<Confession> load() {
        List<Confession> confessionList = new ArrayList<>();
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        try{
            // 和数据库建立连接
            connection = ConnectionDB.getConnection();
            // 借助 PreparedStatement 拼接 SQL 语句
            String sql = "select * from confession";
            statement = connection.prepareStatement(sql);
            // 执行 SQL 语句
            resultSet = statement.executeQuery();
            // 遍历结果集
            while (resultSet.next()){
                Confession confession = new Confession();
                confession.from = resultSet.getString("from");
                confession.to = resultSet.getString("to");
                confession.message = resultSet.getString("message");
                confessionList.add(confession);
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            // 关闭释放资源
            ConnectionDB.close(connection,statement,resultSet);
        }
        return confessionList;
    }

    /**
     * 向文件夹中加载数据
     * @return
     */
    private List<Confession> load1() {
        List<Confession> confessionList = new ArrayList<>();
        // 此处我们需要按行读取. FileReader 本身不支持. 需要套上一层 BufferedReader
        try(BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath))) {
            while(true){
                String line = bufferedReader.readLine();
                // line=null的时候 读完了
                if (line == null){
                    break;
                }
                // 设定存储的时候每行的内容是按 \t 的方法存储
                // 所以读取每行,然后按 \t的方法进行 分割
                String[] res = line.split("\t");
                Confession confession = new Confession();
                confession.from = res[0];
                confession.to = res[1];
                confession.message = res[2];

                confessionList.add(confession);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return confessionList;
    }

    // 这个用来处理客户端提交数据给服务器
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Confession confession = objectMapper.readValue(req.getInputStream(),Confession.class);
        //confessionList.add(confession);

        save1(confession);

        resp.setContentType("application/json;charset=utf-8");
        resp.getWriter().write("{\"ok\":1}");
    }

    /**
     * 从数据库中写入数据
     * @param confession
     */
    private void save(Confession confession) {
        Connection connection = null;
        PreparedStatement statement = null;
        try {
            // 1. 先和数据库建立连接
            connection = ConnectionDB.getConnection();
            // 2. 构造拼装 SQL
            String sql = "insert into confession values (?,?,?)";
            // 这里的 ? 号是占位符,下标是从1开始
            statement = connection.prepareStatement(sql);
            statement.setString(1,confession.from);
            statement.setString(2,confession.to);
            statement.setString(3,confession.message);
            // 3. 执行 SQL
            int ret = statement.executeUpdate();
            // 这里 ret 表示的是受影响的行数,如果为1才是插入成功
            if(ret == 1){
                System.out.println("插入成功!");
            }else {
                System.out.println("插入失败!");
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            ConnectionDB.close(connection,statement,null);
        }
    }

    /**
     * 向文件夹中写入数据
     * @param confession
     */
    private void save1(Confession confession) {
        // 这里的 true 表示追加写状态,表示不清空文件,而是从文件后面继续写
        try(FileWriter fileWriter = new FileWriter(filePath,true)) {
            // 按照约定好的方法写入数据
            fileWriter.write(confession.from+"\t"+confession.to+"\t"+confession.message+"\n");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
